<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>大型数据表格查看器</title>
    <!-- 引入 Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- 引入 Font Awesome -->
    <link
      href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css"
      rel="stylesheet"
    />

    <!-- Tailwind 配置 -->
    <script>
      tailwind.config = {
        darkMode: "class",
        theme: {
          extend: {
            colors: {
              primary: "#3B82F6",
              secondary: "#64748B",
            },
            fontFamily: {
              sans: ["Inter", "system-ui", "sans-serif"],
            },
          },
        },
      };
    </script>

    <!-- 自定义工具类 -->
    <style type="text/tailwindcss">
      @layer utilities {
        .content-auto {
          content-visibility: auto;
        }
        .table-wrapper {
          @apply overflow-x-auto relative shadow-md sm:rounded-lg;
        }
        .table-cell {
          @apply px-3 py-2 text-sm whitespace-nowrap;
        }
        .pagination-btn {
          @apply px-3 py-1 rounded border transition-all duration-200 
               hover:bg-primary hover:text-white hover:border-primary;
        }
        .pagination-btn.active {
          @apply bg-primary text-white border-primary;
        }
      }
    </style>
  </head>

  <body
    class="bg-gray-50 text-gray-800 dark:bg-gray-900 dark:text-gray-100 min-h-screen transition-colors duration-300"
  >
    <!-- 顶部导航栏 -->
    <header
      class="bg-white dark:bg-gray-800 shadow-sm sticky top-0 z-10 transition-colors duration-300"
    >
      <div
        class="container mx-auto px-4 py-3 flex justify-between items-center"
      >
        <h1 class="text-xl font-bold text-primary">大型数据表格查看器</h1>

        <div class="flex items-center space-x-4">
          <!-- 暗黑模式切换 -->
          <button
            id="theme-toggle"
            class="p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors"
          >
            <i class="fa fa-moon-o dark:hidden text-gray-600"></i>
            <i class="fa fa-sun-o hidden dark:block text-yellow-300"></i>
          </button>

          <!-- 每页显示数量选择 -->
          <div class="flex items-center space-x-2">
            <label for="per-page" class="text-sm">每页:</label>
            <select
              id="per-page"
              class="bg-gray-100 dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary"
            >
              <option value="10">10</option>
              <option value="20">20</option>
              <option value="50">50</option>
              <option value="100">100</option>
            </select>
          </div>
        </div>
      </div>
    </header>

    <!-- 主内容区 -->
    <main class="container mx-auto px-4 py-6">
      <!-- 表格信息统计 -->
      <div
        class="mb-4 flex flex-col sm:flex-row justify-between items-start sm:items-center space-y-2 sm:space-y-0"
      >
        <div class="text-sm text-gray-600 dark:text-gray-400">
          总计: <span id="total-rows" class="font-medium">200</span> 行 |
          <span id="total-cols" class="font-medium">200</span> 列
        </div>

        <!-- 搜索框 -->
        <div class="relative w-full sm:w-auto">
          <input
            type="text"
            id="search-input"
            placeholder="搜索..."
            class="pl-8 pr-3 py-1.5 w-full sm:w-64 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 focus:outline-none focus:ring-1 focus:ring-primary"
          />
          <i
            class="fa fa-search absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"
          ></i>
        </div>
      </div>

      <!-- 表格容器 -->
      <div
        class="table-wrapper mb-6 bg-white dark:bg-gray-800 transition-colors duration-300"
      >
        <table class="w-full text-left">
          <thead class="bg-gray-100 dark:bg-gray-700">
            <tr id="table-header"></tr>
          </thead>
          <tbody
            id="table-body"
            class="divide-y divide-gray-200 dark:divide-gray-700"
          ></tbody>
        </table>
      </div>

      <!-- 分页控制 -->
      <div
        id="pagination"
        class="flex flex-col sm:flex-row justify-between items-center space-y-3 sm:space-y-0"
      >
        <div class="text-sm text-gray-600 dark:text-gray-400">
          显示 <span id="showing-from" class="font-medium">1</span> 到
          <span id="showing-to" class="font-medium">10</span> 条，共
          <span id="pagination-total" class="font-medium">200</span> 条
        </div>

        <div class="flex items-center space-x-1">
          <button id="first-page" class="pagination-btn" title="第一页">
            <i class="fa fa-angle-double-left"></i>
          </button>
          <button id="prev-page" class="pagination-btn" title="上一页">
            <i class="fa fa-angle-left"></i>
          </button>
          <div id="page-numbers" class="flex items-center space-x-1"></div>
          <button id="next-page" class="pagination-btn" title="下一页">
            <i class="fa fa-angle-right"></i>
          </button>
          <button id="last-page" class="pagination-btn" title="最后一页">
            <i class="fa fa-angle-double-right"></i>
          </button>
        </div>
      </div>
    </main>

    <!-- 页脚 -->
    <footer
      class="bg-white dark:bg-gray-800 shadow-inner mt-8 py-4 transition-colors duration-300"
    >
      <div
        class="container mx-auto px-4 text-center text-sm text-gray-600 dark:text-gray-400"
      >
        大型数据表格查看器 &copy; 2023
      </div>
    </footer>

    <script>
      // 数据配置
      const TOTAL_ROWS = 200;
      const TOTAL_COLS = 200;
      let currentPage = 1;
      let rowsPerPage = 10;
      let searchTerm = "";

      // DOM 元素
      const tableHeader = document.getElementById("table-header");
      const tableBody = document.getElementById("table-body");
      const pageNumbers = document.getElementById("page-numbers");
      const prevPageBtn = document.getElementById("prev-page");
      const nextPageBtn = document.getElementById("next-page");
      const firstPageBtn = document.getElementById("first-page");
      const lastPageBtn = document.getElementById("last-page");
      const perPageSelect = document.getElementById("per-page");
      const themeToggle = document.getElementById("theme-toggle");
      const searchInput = document.getElementById("search-input");
      const showingFromEl = document.getElementById("showing-from");
      const showingToEl = document.getElementById("showing-to");
      const paginationTotalEl = document.getElementById("pagination-total");

      // 初始化页面
      function init() {
        // 检查用户主题偏好
        if (
          localStorage.theme === "dark" ||
          (!("theme" in localStorage) &&
            window.matchMedia("(prefers-color-scheme: dark)").matches)
        ) {
          document.documentElement.classList.add("dark");
        } else {
          document.documentElement.classList.remove("dark");
        }

        // 生成表头
        generateTableHeader();

        // 生成表格数据并渲染
        renderTable();

        // 绑定事件监听
        bindEvents();
      }

      // 生成表头
      function generateTableHeader() {
        // 清空现有表头
        tableHeader.innerHTML = "";

        // 添加行号列
        const rowNumberHeader = document.createElement("th");
        rowNumberHeader.className =
          "table-cell font-semibold bg-gray-200 dark:bg-gray-600 sticky left-0 z-10";
        rowNumberHeader.textContent = "行号";
        tableHeader.appendChild(rowNumberHeader);

        // 添加数据列
        for (let i = 0; i < TOTAL_COLS; i++) {
          const th = document.createElement("th");
          th.className = "table-cell font-semibold";
          th.textContent = `列 ${i + 1}`;
          tableHeader.appendChild(th);
        }
      }

      // 生成表格数据
      function generateTableData() {
        const data = [];

        for (let i = 0; i < TOTAL_ROWS; i++) {
          const row = [];
          // 行号
          row.push(i + 1);

          // 生成随机数据
          for (let j = 0; j < TOTAL_COLS; j++) {
            // 生成随机数据，可以是数字或简短文本
            if (Math.random() > 0.7) {
              row.push(`文本 ${i + 1}-${j + 1}`);
            } else {
              row.push(Math.floor(Math.random() * 10000));
            }
          }

          data.push(row);
        }

        return data;
      }

      // 过滤数据
      function filterData(data) {
        if (!searchTerm) return data;

        const term = searchTerm.toLowerCase();
        return data.filter((row) => {
          // 检查行中是否有匹配搜索词的数据
          return row.some((cell) => {
            return cell.toString().toLowerCase().includes(term);
          });
        });
      }

      // 渲染表格
      function renderTable() {
        // 生成完整数据
        const allData = generateTableData();
        // 过滤数据
        const filteredData = filterData(allData);
        const totalFiltered = filteredData.length;

        // 更新统计信息
        paginationTotalEl.textContent = totalFiltered;

        // 计算分页
        const totalPages = Math.ceil(totalFiltered / rowsPerPage);
        // 确保当前页在有效范围内
        currentPage = Math.min(Math.max(currentPage, 1), totalPages || 1);

        // 计算当前页显示的数据范围
        const startIndex = (currentPage - 1) * rowsPerPage;
        const endIndex = Math.min(startIndex + rowsPerPage, totalFiltered);
        const currentData = filteredData.slice(startIndex, endIndex);

        // 更新显示范围
        showingFromEl.textContent = totalFiltered > 0 ? startIndex + 1 : 0;
        showingToEl.textContent = endIndex;

        // 清空表格体
        tableBody.innerHTML = "";

        // 渲染当前页数据
        currentData.forEach((row, rowIndex) => {
          const tr = document.createElement("tr");
          // 修复隔行变色问题，为暗黑模式使用合适的颜色
          if (rowIndex % 2 === 0) {
            tr.className = "bg-white dark:bg-gray-800";
          } else {
            tr.className = "bg-gray-450 dark:bg-gray-750";
          }
          tr.className +=
            " hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-150";

          row.forEach((cell, cellIndex) => {
            const td = document.createElement("td");
            td.className = "table-cell";

            // 行号列固定在左侧
            if (cellIndex === 0) {
              td.className += " dark:bg-gray-800 sticky left-0 font-medium";
              // 为行号列添加与所在行匹配的背景色
              if (rowIndex % 2 !== 0) {
                td.className += " bg-gray-450 dark:bg-gray-750";
              } else {
                td.className += " bg-white dark:bg-gray-800";
              }
            }

            td.textContent = cell;
            tr.appendChild(td);
          });

          tableBody.appendChild(tr);
        });

        // 渲染分页
        renderPagination(totalPages);

        // 更新分页按钮状态
        updatePaginationButtons(totalPages);
      }

      // 渲染分页
      function renderPagination(totalPages) {
        // 清空现有页码
        pageNumbers.innerHTML = "";

        // 没有数据时不显示页码
        if (totalPages === 0) return;

        // 计算显示的页码范围（最多显示9个页码）
        let startPage = Math.max(1, currentPage - 4);
        let endPage = Math.min(totalPages, startPage + 8);

        // 如果接近末尾，调整起始页
        if (endPage - startPage < 8 && startPage > 1) {
          startPage = Math.max(1, endPage - 8);
        }

        // 添加省略号（如果需要）
        if (startPage > 1) {
          const ellipsis = document.createElement("span");
          ellipsis.className = "px-2 text-gray-500";
          ellipsis.textContent = "...";
          pageNumbers.appendChild(ellipsis);
        }

        // 添加页码
        for (let i = startPage; i <= endPage; i++) {
          const button = document.createElement("button");
          button.className = `pagination-btn ${
            i === currentPage ? "active" : ""
          }`;
          button.textContent = i;
          button.addEventListener("click", () => {
            currentPage = i;
            renderTable();
          });
          pageNumbers.appendChild(button);
        }

        // 添加省略号（如果需要）
        if (endPage < totalPages) {
          const ellipsis = document.createElement("span");
          ellipsis.className = "px-2 text-gray-500";
          ellipsis.textContent = "...";
          pageNumbers.appendChild(ellipsis);
        }
      }

      // 更新分页按钮状态
      function updatePaginationButtons(totalPages) {
        prevPageBtn.disabled = currentPage === 1;
        nextPageBtn.disabled = currentPage === totalPages || totalPages === 0;
        firstPageBtn.disabled = currentPage === 1;
        lastPageBtn.disabled = currentPage === totalPages || totalPages === 0;

        if (prevPageBtn.disabled) {
          prevPageBtn.classList.add(
            "opacity-50",
            "cursor-not-allowed",
            "hover:bg-transparent",
            "hover:text-gray-800",
            "hover:border-gray-300",
            "dark:hover:text-gray-100",
            "dark:hover:border-gray-600"
          );
          prevPageBtn.classList.remove(
            "hover:bg-primary",
            "hover:text-white",
            "hover:border-primary"
          );
        } else {
          prevPageBtn.classList.remove(
            "opacity-50",
            "cursor-not-allowed",
            "hover:bg-transparent",
            "hover:text-gray-800",
            "hover:border-gray-300",
            "dark:hover:text-gray-100",
            "dark:hover:border-gray-600"
          );
          prevPageBtn.classList.add(
            "hover:bg-primary",
            "hover:text-white",
            "hover:border-primary"
          );
        }

        if (nextPageBtn.disabled) {
          nextPageBtn.classList.add(
            "opacity-50",
            "cursor-not-allowed",
            "hover:bg-transparent",
            "hover:text-gray-800",
            "hover:border-gray-300",
            "dark:hover:text-gray-100",
            "dark:hover:border-gray-600"
          );
          nextPageBtn.classList.remove(
            "hover:bg-primary",
            "hover:text-white",
            "hover:border-primary"
          );
        } else {
          nextPageBtn.classList.remove(
            "opacity-50",
            "cursor-not-allowed",
            "hover:bg-transparent",
            "hover:text-gray-800",
            "hover:border-gray-300",
            "dark:hover:text-gray-100",
            "dark:hover:border-gray-600"
          );
          nextPageBtn.classList.add(
            "hover:bg-primary",
            "hover:text-white",
            "hover:border-primary"
          );
        }

        // 第一页和最后一页按钮应用相同的禁用样式
        firstPageBtn.className = prevPageBtn.className;
        lastPageBtn.className = nextPageBtn.className;
      }

      // 绑定事件
      function bindEvents() {
        // 上一页
        prevPageBtn.addEventListener("click", () => {
          if (currentPage > 1) {
            currentPage--;
            renderTable();
          }
        });

        // 下一页
        nextPageBtn.addEventListener("click", () => {
          const totalPages = Math.ceil(
            filterData(generateTableData()).length / rowsPerPage
          );
          if (currentPage < totalPages) {
            currentPage++;
            renderTable();
          }
        });

        // 第一页
        firstPageBtn.addEventListener("click", () => {
          if (currentPage !== 1) {
            currentPage = 1;
            renderTable();
          }
        });

        // 最后一页
        lastPageBtn.addEventListener("click", () => {
          const totalPages = Math.ceil(
            filterData(generateTableData()).length / rowsPerPage
          );
          if (currentPage !== totalPages && totalPages > 0) {
            currentPage = totalPages;
            renderTable();
          }
        });

        // 每页显示数量变更
        perPageSelect.addEventListener("change", () => {
          rowsPerPage = parseInt(perPageSelect.value);
          currentPage = 1; // 重置到第一页
          renderTable();
        });

        // 暗黑模式切换
        themeToggle.addEventListener("click", () => {
          if (document.documentElement.classList.contains("dark")) {
            document.documentElement.classList.remove("dark");
            localStorage.theme = "light";
          } else {
            document.documentElement.classList.add("dark");
            localStorage.theme = "dark";
          }
          // 切换主题后重新渲染表格以确保样式正确
          renderTable();
        });

        // 搜索功能
        searchInput.addEventListener("input", (e) => {
          searchTerm = e.target.value.trim();
          currentPage = 1; // 重置到第一页
          renderTable();
        });

        // 支持键盘导航
        document.addEventListener("keydown", (e) => {
          const totalPages = Math.ceil(
            filterData(generateTableData()).length / rowsPerPage
          );

          if (e.key === "ArrowLeft") {
            if (currentPage > 1) {
              currentPage--;
              renderTable();
            }
          } else if (e.key === "ArrowRight") {
            if (currentPage < totalPages) {
              currentPage++;
              renderTable();
            }
          }
        });
      }

      // 初始化
      document.addEventListener("DOMContentLoaded", init);
    </script>
  </body>
</html>
